package com.smt.modules.bus.service.impl;

import com.smt.common.utils.*;
import com.smt.modules.bus.entity.*;
import com.smt.modules.bus.service.*;
import com.smt.modules.bus.vo.MessageHandleVo;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import com.smt.modules.bus.dao.MessageHandleDao;


@Service("messageHandleService")
public class MessageHandleServiceImpl extends ServiceImpl<MessageHandleDao, MessageHandleEntity> implements MessageHandleService {

    @Autowired
    private ProjectService projectService;

    @Autowired
    private ProjectTaskService projectTaskService;

    @Autowired
    private SubtaskService subtaskService;

    @Autowired
    private TeamService teamService;


    /**
     * 消息中间段分割
     */
    public static final String MESSAGE_SPLIT = "-";

    /**
     * 子消息拆分
     */
    public static final String MESSAGE_SUB_SPLIT = "@";

    /**
     * 阶段拆分任务
     */
    public static final String MESSAGE_SUB_STAGE = "#";



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<MessageHandleEntity> page = this.selectPage(
                new Query<MessageHandleEntity>(params).getPage(),
                new EntityWrapper<MessageHandleEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R unreadCount(MessageHandleVo messageHandleVo) {
        Long receviceUser = messageHandleVo.getReceviceUser();
        Long projectId = messageHandleVo.getProjectId();
        int count = selectCount(new EntityWrapper<MessageHandleEntity>()
                .eq("recevice_user", receviceUser)
                .eq("is_delete", 0)
                .eq("status", 0));
        return R.ok("获取未读条数").put("code",1000).put("count",count);
    }

    @Override
    public R getMessages(Long id) {
        MessageHandleEntity messageHandleEntity = selectById(id);
        return R.ok().put("messageEntity",messageHandleEntity);
    }


    /**
     * 消息持久化
     *
     * @param messageStr
     */
    @Async
    @Override
    public void decoderMessage(String messageStr) {
        //分解消息
        //消息格式：
        // 项目全员发送消息-0@81
        // 独立发送消息-1@0,67
        // 指定用户消息发送-1@0,68,67
        //发送给阶段成员下的所有任务和子任务负责人-2@81#6（81：项目id 6：阶段id）
        //发送给任务下的所有子任务负责人-3@1345
        String[] split = messageStr.split(MESSAGE_SPLIT);
        //消息体
        String messageBody = split[0];
        //子消息
        String subMessage = split[1];
        String[] subMessageArray = subMessage.split(MESSAGE_SUB_SPLIT);
        //子消息内容
        String subMessageStr = subMessageArray[1];
        //消息类型
        Integer messageType = Integer.parseInt(subMessageArray[0]);

        switch (messageType){
            case 0:
                saveAllProjectMessage(messageBody,Long.parseLong(subMessageStr));
                break;
            case 1:
                StringToListUtil stringToListUtil = new StringToListUtil();
                List<Long> oneList = stringToListUtil.encode(Long.class, subMessageStr);
                if(!Objects.isNull(oneList) && oneList.size() != 0){
                    //项目id
                    Long projectId = oneList.get(0);
                    for(int i = 1; i < oneList.size();i++){
                        //存储其用户信息
                        saveUserMessage(messageBody,projectId,oneList.get(i));
                    }
                }
                break;
            case 2:
                //拆分阶段任务
                String[] stageTask = subMessageStr.split(MESSAGE_SUB_STAGE);
                String proId = stageTask[0];
                String stageId = stageTask[1];
                saveAllStageUser(messageBody,Long.parseLong(proId),Integer.parseInt(stageId));
                break;
            case 3:
                saveAllTaskMessage(messageBody,Long.parseLong(subMessageStr));
                break;
                default:
                    break;
        }
    }

    /**
     * 获取消息集合
     *
     * @param messageHandleVo
     * @return
     */
    @Override
    public R getMessageList(MessageHandleVo messageHandleVo) {
        Long receviceUser = messageHandleVo.getReceviceUser();
        Long projectId = messageHandleVo.getProjectId();
        List<MessageHandleEntity> messageHandleEntities = selectList(new EntityWrapper<MessageHandleEntity>()
                .eq("recevice_user", receviceUser)
                .eq("is_delete", 0)
                .orderBy("create_time",false));
        return R.ok("获取消息集合成功").put("msgContent",messageHandleEntities);
    }

    /**
     * 保存项目发送给所有人的消息
     *
     * @return
     */
    private boolean saveAllProjectMessage(String message,Long projectId){
        boolean[] flag = new boolean[]{false};
        List<TeamEntity> teamEntities = teamService.selectList(new EntityWrapper<TeamEntity>()
                .eq("project_id", projectId)
                .eq("member_exist", 0));
        ProjectEntity projectEntity = projectService.selectById(projectId);
        teamEntities.stream().forEach(t -> {
            Long memberId = t.getMemberId();
            Date date = new Date(System.currentTimeMillis());
            String projectName = projectEntity.getProjectName();
            //保存消息
            MessageHandleVo messageHandleVo = new MessageHandleVo(0,
                    message,
                    memberId,
                    projectId,
                    date,
                    0,
                    0,
                    projectName);
            flag[0] = insert(messageHandleVo.copyPropertiesTo(new MessageHandleEntity()));
        });
        return flag[0];
    }

    /**
     * 存储指定用户的消息信息
     *
     * @param projectId
     * @param userId
     * @return
     */
    public boolean saveUserMessage(String messageBody,Long projectId, Long userId) {
        ProjectEntity projectEntity = projectService.selectById(projectId);
        Date nowDate = new Date(System.currentTimeMillis());
        if(!Objects.isNull(projectEntity)) {
            MessageHandleVo messageHandleVo = new MessageHandleVo(1,
                    messageBody,
                    userId,
                    projectId,
                    nowDate,
                    projectEntity.getProjectName());
            boolean insert = insert(messageHandleVo.copyPropertiesTo(new MessageHandleEntity()));
            return insert;
        }else{
            return false;
        }
    }


    /**
     * 存储项目阶段下的所有用户消息
     *
     * @param messageBody
     * @param projectId
     * @param stageId
     * @return
     */
    public boolean saveAllStageUser(String messageBody,Long projectId, Integer stageId) {
        Boolean[] flags = null;
        ProjectEntity projectEntity = projectService.selectById(projectId);
        if(!Objects.isNull(projectEntity)) {
            List<ProjectTaskEntity> projectTaskEntityList = projectTaskService.selectList(new EntityWrapper<ProjectTaskEntity>()
                    .eq("project_id", projectId)
                    .eq("stage_id", stageId)
                    .eq("status", Constant.SQL_CON)
                    .eq("member_exist", 0));
            if(!Objects.isNull(projectTaskEntityList) && projectTaskEntityList.size() != 0){
                flags = new Boolean[projectTaskEntityList.size()];
                int index = 0;
                Set<Long> idSets = new HashSet<>();
                for(ProjectTaskEntity p : projectTaskEntityList) {
                    Long memberId = p.getMemberId();
                    idSets.add(memberId);
                }
                Iterator<Long> iterator = idSets.iterator();
                while(iterator.hasNext()){
                    Long memberId = iterator.next();
                    Date nowDate = DateTime.now().toDate();
                    MessageHandleVo messageHandleVo = new MessageHandleVo(2,
                            messageBody,
                            memberId,
                            projectId,
                            stageId,
                            nowDate,
                            projectEntity.getProjectName());
                    flags[index++] = insert(messageHandleVo.copyPropertiesTo(new MessageHandleEntity()));
                }
            }
            if(Objects.isNull(flags)){
                return false;
            }else {
                boolean resultFlag = true;
                //批次插入全部都得成功
                for(boolean b : flags){
                    if(!b){
                        resultFlag = false;
                        break;
                    }
                }
                    return resultFlag;
            }
        }else{
            return false;
        }
    }

    /**
     * 存储任务下的所有用户消息
     *
     * @param messageBody
     * @param taskId
     * @return
     */
    public boolean saveAllTaskMessage(String messageBody,Long taskId) {
        List<SubtaskEntity> subtaskEntities = subtaskService.selectList(new EntityWrapper<SubtaskEntity>()
                .eq("project_task_id", taskId)
                .eq("status", Constant.SQL_CON)
                .eq("member_exist", 0));
        ProjectTaskEntity projectTaskEntity = projectTaskService.selectById(taskId);
        if(!Objects.isNull(subtaskEntities) && subtaskEntities.size() != 0){
            Long projectId = projectTaskEntity.getProjectId();
            ProjectEntity projectEntity = projectService.selectById(projectId);
            subtaskEntities.stream().forEach(s -> {
                Long memberId = s.getMemberId();
                String projectName = projectEntity.getProjectName();
                Long projectEntityId = projectEntity.getId();
                MessageHandleVo messageHandleVo = new MessageHandleVo(3,
                        messageBody,
                        memberId,
                        projectEntityId,
                        taskId,
                        s.getId(),
                        new Date(System.currentTimeMillis()),
                        projectName);
                insert(messageHandleVo.copyPropertiesTo(new MessageHandleEntity()));
            });
        }
        return true;
    }
    /**
     * 存储消息
     *
     * @param messageHandle
     * @return
     */
    @Override
    public R save(MessageHandleVo messageHandle) {
        boolean insert = insert(messageHandle.copyPropertiesTo(new MessageHandleEntity()));
        return insert?R.ok():R.error();
    }

}
